package com.kb.service.impl;

import cn.hutool.crypto.digest.DigestUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import com.alibaba.excel.util.StringUtils;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.kb.common.ApiResponse;
import com.kb.domain.icQuote.OrderTo;
import com.kb.domain.icQuote.Product;
import com.kb.domain.icQuote.QueryTO;
import com.kb.domain.icQuote.SKU;
import com.kb.entity.icQuote.Token;
import com.kb.mapper.mysql.icQuote.TokenMapper;
import com.kb.service.QuoteService;
import io.swagger.annotations.Api;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.ImportResource;
import org.springframework.stereotype.Service;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.time.Instant;

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import java.util.*;

import org.apache.commons.codec.digest.DigestUtils;

import javax.annotation.Resource;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.time.Instant;
import java.util.Map;
import java.util.stream.Collectors;
import okhttp3.FormBody;
@Service
@DS("master")
@Slf4j
public class QuoteServiceImpl implements QuoteService {

    @Value("${icquote.appId}")
    private   String appId ;
    @Value("${icquote.appKey}")
    private   String appKey ;
    @Value("${icquote.requestUrl}")
    private   String requestUrl ;


    @Resource
    private TokenMapper tokenMapper;

    @Override
    public String updateToken() {
        // Step 1: Get current timestamp
        long timestamp = Instant.now().getEpochSecond();

        // Step 2: Prepare parameters
        Map<String, String> params = new HashMap<>();
        params.put("_t", String.valueOf(timestamp));
        params.put("appid", appId);

        // Step 3: Create query string and append appKey
        String queryString = params.entrySet().stream()
                .sorted(Map.Entry.comparingByKey())
                .map(entry -> entry.getKey() + "=" + entry.getValue())
                .collect(Collectors.joining("&"));
        String stringToSign = queryString + "|" + appKey;

        // Step 4: Calculate MD5 signature using Hutool
        String sign = DigestUtil.md5Hex(stringToSign);

        // Step 5: Create JSON object using Hutool
        Map<String, Object> jsonMap = new HashMap<>();
        jsonMap.put("_t", timestamp);
        jsonMap.put("appid", appId);
        jsonMap.put("sign", sign);
        String json = JSONUtil.toJsonStr(jsonMap);

        // Step 6: Send HTTP POST request and process response
        String response = sendPostRequest(requestUrl+"/v2/new-token/create", json);
        String token = extractTokenFromResponse(response);
        System.out.println("Extracted token: " + token);

        Long time=extractTimeFromResponse(response);

            if(StringUtils.isNotBlank(token)&&time!=null){
                QueryWrapper<Token> wrapper=new QueryWrapper();
                wrapper.eq("type",1);
                Token existingToken=tokenMapper.selectOne(wrapper);

                if (existingToken == null) {
                    Token newToken = new Token();
                    newToken.setToken(token);
                    newToken.setExpireTime(time);
                    newToken.setType(1);
                    tokenMapper.insert(newToken);
                } else {
                    existingToken.setExpireTime(time);
                    existingToken.setToken(token);
                    tokenMapper.updateById(existingToken);
                }


            }
        return token;

    }

    @Override
    public   List<Product> query(QueryTO to) {
        if(StringUtils.isNotBlank(to.getKeyWord())){
            String token = getToken(1);
            long timestamp = Instant.now().getEpochSecond();
            Map<String, Object> jsonMap = new HashMap<>();
            jsonMap.put("_t", timestamp);
            jsonMap.put("token", token);
            jsonMap.put("keyword", to.getKeyWord());
            String json = JSONUtil.toJsonStr(jsonMap);

            String response = sendPostRequest(requestUrl+"/search-v1/products/get-single-goods-new", json);


            // 解析整个 JSON 响应
            JSONObject jsonObject = JSONUtil.parseObj(response);

            // 判断 success 字段
            boolean success = jsonObject.getBool("success", false);
            if (!success) {
                System.out.println("Request failed: " + jsonObject.getStr("message"));
                return null;
            }

            // 获取 result 数组
            JSONArray resultArray = jsonObject.getJSONArray("result");

            List<Product> productList=new ArrayList<>();
            // 处理每个 product 对象
            for (int i = 0; i < resultArray.size(); i++) {
                JSONObject resultObject = resultArray.getJSONObject(i);
                Product product = JSONUtil.toBean(resultObject, Product.class);
                product.setPackageName(resultObject.getStr("package"));
                productList.add(product);
            }

            return productList;
        }
        return new ArrayList<>();
    }

    @Override
    public ApiResponse order(OrderTo to) {
        String token = getToken(1);
        long timestamp = Instant.now().getEpochSecond();

        // Prepare the form data
        FormBody.Builder formBuilder = new FormBody.Builder();
        formBuilder.add("_t", String.valueOf(timestamp));
        formBuilder.add("token", token);
        if(StringUtils.isNotBlank(to.getUserMark())){
            formBuilder.add("user_mark", to.getUserMark());
        }


        List<SKU> skuList = to.getSkuList();

        // Add items to the form data
        for (int i = 0; i < skuList.size(); i++) {
            SKU sku = skuList.get(i);
            formBuilder.add("items[" + i + "][pro_num]", sku.getNum().toString());
            formBuilder.add("items[" + i + "][sku]", sku.getSku());
        }

        // Build the form body
        FormBody formBody = formBuilder.build();

        // Send POST request with form data
        String response = sendPostRequest(requestUrl + "/api-v1/cart/batch-add", formBody);

        StringBuilder resultBuilder = new StringBuilder();

        log.info("云汉购物车返回:"+response);

        JSONObject jsonResponse = JSONUtil.parseObj(response);

        // 获取失败结果列表
        JSONObject result = jsonResponse.getJSONObject("result");
        JSONArray failResult = result.getJSONArray("fail_result");

        // 如果有失败的结果
        if (failResult != null && !failResult.isEmpty()) {
            // 遍历失败结果
            for (int i = 0; i < failResult.size(); i++) {
                JSONObject failItem = failResult.getJSONObject(i);
                String errorCode = failItem.getStr("sku");
                String errorMessage = failItem.getStr("error_message");

                // 构建失败信息
                if (i > 0) {
                    resultBuilder.append(", ");
                }
                resultBuilder.append("失败型号：").append(errorCode)
                        .append("，").append(errorMessage);
            }
            return ApiResponse.error(resultBuilder.toString());

        }else{
            ObjectMapper objectMapper = new ObjectMapper();
            List<Integer> cartIdList = new ArrayList<>();

            try {
                JsonNode rootNode = objectMapper.readTree(response);
                JsonNode successResultNode = rootNode.path("result").path("success_result");

                for (JsonNode node : successResultNode) {
                    int cartId = node.path("cart_id").asInt();
                    cartIdList.add(cartId);
                }

                // 输出 cartIdList 以验证结果
                System.out.println(cartIdList);
                if(cartIdList!=null&&cartIdList.size()>0){


                    FormBody.Builder builder = new FormBody.Builder();
                    builder.add("_t", String.valueOf(timestamp));
                    builder.add("token", token);
                    builder.add("user_mark", to.getUserMark());
                    if(StringUtils.isNotBlank(to.getRemarks()))
                    builder.add("remarks", to.getRemarks());
                    if(StringUtils.isNotBlank(to.getUserOrderCode()))
                    builder.add("user_order_code", to.getUserOrderCode());
                    builder.add("store_id", "1");



                    for (int i = 0; i < cartIdList.size(); i++) {
                        Integer orderId = cartIdList.get(i);
                        JsonNode matchedNode = successResultNode.get(i);
                        String matchedSku = matchedNode.path("sku").asText();

                        // 找到与 matchedSku 相同的 skuList 项
                        SKU matchingSku = skuList.stream()
                                .filter(sku -> sku.getSku().equals(matchedSku))
                                .findFirst()
                                .orElse(null);

                        if (matchingSku != null) {
                            builder.add("items[" + i + "][id]", String.valueOf(orderId));
                            if(StringUtils.isNotBlank(matchingSku.getMaterialCode()))
                            builder.add("items[" + i + "][user_goods_code]", matchingSku.getMaterialCode());
                            if(StringUtils.isNotBlank(matchingSku.getDateCode()))
                            builder.add("items[" + i + "][date_code]", matchingSku.getDateCode());
                        }
                    }


                    FormBody body = builder.build();

                    // Send POST request with form data
                    String rsp = sendPostRequest(requestUrl + "/api-v1/order/add", body);
                    log.info("云汉下单返回:"+rsp);

                     objectMapper = new ObjectMapper();
                    String formattedString = "";
                        // 解析 JSON 字符串
                         rootNode = objectMapper.readTree(rsp);

                    String  message = rootNode.path("message").asText();

                    if(StringUtils.isNotBlank(message))
                        return ApiResponse.error(message);


                        JsonNode resultNode = rootNode.path("result");

                        // 提取订单号和收货地址
                        String orderCode = resultNode.path("order_code").asText();
                        return ApiResponse.success(orderCode);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }


        return null;

    }
    private String convertToJson(Map<String, Object> map) {
        // Use a JSON library to convert map to JSON string
        // For example, using Jackson
        ObjectMapper objectMapper = new ObjectMapper();
        try {
            return objectMapper.writeValueAsString(map);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
            return "{}";
        }
    }
    private String sendPostRequest(String url, FormBody formBody) {
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
                .url(url)
                .post(formBody)
                .build();

        try (Response response = client.newCall(request).execute()) {
            if (response.isSuccessful()) {
                return response.body().string();
            } else {
                throw new IOException("Unexpected code " + response);
            }
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    public String sendPostRequest(String requestUrl, String jsonInputString) {
        StringBuilder response = new StringBuilder();
        try {
            URL url = new URL(requestUrl);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Content-Type", "application/json; utf-8");
            conn.setRequestProperty("Accept", "application/json");
            conn.setDoOutput(true);

            // Write JSON data to the request
            try (OutputStream os = conn.getOutputStream()) {
                byte[] input = jsonInputString.getBytes("utf-8");
                os.write(input, 0, input.length);
            }

            // Read the response
            try (BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"))) {
                String responseLine;
                while ((responseLine = br.readLine()) != null) {
                    response.append(responseLine.trim());
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return response.toString();
    }

    private String extractTokenFromResponse(String response) {
        JSONObject jsonObject = JSONUtil.parseObj(response);
        JSONObject result = jsonObject.getJSONObject("result");
        return result.getStr("token");
    }

    private Long extractTimeFromResponse(String response) {
        JSONObject jsonObject = JSONUtil.parseObj(response);
        JSONObject result = jsonObject.getJSONObject("result");
        return result.getLong("expireTime");
    }


    private String getToken(Integer type){
        QueryWrapper<Token> wrapper=new QueryWrapper();
        wrapper.eq("type",type);

        Token existingToken=tokenMapper.selectOne(wrapper);

        if(existingToken!=null){
            return existingToken.getToken();
        }else{
            return updateToken();
        }



    }

}
